home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / program / oxcc1434.zip / SRC / CFAR.C < prev    next >
C/C++ Source or Header  |  1995-11-15  |  46KB  |  1,882 lines

  1. /* cfar.c */
  2. /* Import .o and .a (a.out format) files into a cff archive */
  3. /* Version 2 now incorporates FILE mode, absorbing 'cfin' and 'cfdel' */
  4. /* Copyright 1993, 1995 Norman D. Culver, All Rights Reserved */
  5.  
  6. /* compile: gcc -o -O2 -DSKELETON cfar.c */
  7.  
  8. typedef unsigned long size_t;
  9.  
  10. #include "oxbow.h"
  11.  
  12. extern void (*BUGPRINTF)(char *fmt, ...);
  13.  
  14. extern long atol(const char *);
  15. extern int strlen(const char *);
  16. extern void *strcpy(char *, const char *);
  17. extern int _strcpy(char *, char *);
  18. extern void memclr(char *, long);
  19. extern int strlwr(char *);
  20. extern void *strrchr(const char *, char);
  21. extern void *strstr(const char *, const char *);
  22. static void setup_origin(unsigned long, int);
  23. extern void oxlink_close_libs(void);
  24.  
  25. /* Program version */
  26. static Item prgversion = (Item)2;
  27. /* Archive version */
  28. static Item arversion;
  29.  
  30. /* Maximum library types */
  31. #define MAXLIBTYPE 16
  32.  
  33. typedef struct {
  34.     unsigned long sn;
  35.     unsigned long libnum : 12;    /* capacity for 4096 libraries per libtype */
  36.     unsigned long libtype : 4;    /* capacity for 16 library types */
  37.     unsigned long unused : 12;
  38.     unsigned long tag : 4;
  39. } SymItem;
  40.  
  41. typedef struct {
  42.     unsigned long filetime;
  43.     unsigned long sn : 28;
  44.     unsigned long tag : 4;
  45. } OrgItem;
  46.  
  47. /* Action bitmap */
  48. static int act;
  49. #define arADD (1)
  50. #define arREPLACE (2)
  51. #define arDELETE (4)
  52. #define arEXTRACT (8)
  53. #define arCHECK (16)
  54. #define arUPDATE (32)
  55.  
  56. static int verbose;            /* if 1, verbose mode */
  57. static long libtype;    /* 0 = modules, 1 = classes */
  58. static long oldlibtype = -1;
  59. static long libnum;        /* library number into which files are stored */
  60. static long oldlibnum = -1;
  61. static int map;            /* if 1, print archive map */
  62. static int map_bitmaps;    /* if 1, and map, print bitmaps */
  63. static int map_entries; /* if 1, and map, print entries */
  64. static int freshen;        /* if 1, freshen entries */
  65. static int shrink;        /* if 1, shrink archive */
  66. static int issymbol;    /* if 1, file names are really symbol names */
  67. static int batfile;        /* if 1, print a batchfile to remake archive */
  68. static void *archive;    /* handle of the open archive */
  69. static void *msyms;        /* handle of the master symbol table */
  70. static void *fipaths;    /* handle of the internal filemode path table */
  71. static void *ipaths;    /* handle of the internal path table */
  72. static void *qipaths;
  73. static void *origins;    /* handle of the origin path table */
  74. static void *qorigins;
  75. static void *lib;            /* handle of the current internal library */
  76. static void *plib;            /* handle of the library parent directory */
  77. static char curlib[1024];        /* internal path to the current library */
  78. static int curliblen;
  79. static char curobj[1024];    /* internal path to the current file */
  80. static int curobjlen;
  81. static char *cur_orgpath;    /* current origin path as given by cfpathtrn */
  82. static int cur_orgtype;        /* current origin type as given by cfpathtrn */
  83. static OrgItem cur_org;        /* current origin time and serial num */
  84. static char ltypes[MAXLIBTYPE];
  85. static char lnums[4096];
  86. static int delete;
  87. static int replace;
  88. static int add;
  89.  
  90. static unsigned long
  91. new_sn(char *name)
  92. {
  93. Item sn;
  94. int namlen = strlen(name);
  95.     if(cffind(archive, name, namlen, &sn) >= FOUND)
  96.     {
  97.         ++sn.a0;
  98.         cfreinsert(archive, name, namlen, &sn);
  99.         return sn.a0;
  100.     }
  101.     return 0;
  102. }
  103.  
  104. /* ++++++++++++++++++++++++++++ DLLMODE ++++++++++++++++++++++++++++++++ */
  105. static int dllmode;
  106.  
  107. static void
  108. proc_dllmode(char *dllpath)
  109. {
  110. char buf[256];
  111. char symbol[256];
  112. char dllname[256];
  113. char dlldef[256];
  114. int ordinal, argcnt, symlen, match, deflen;
  115. int filesize, filesize1;
  116. long dupnum;
  117. SymItem symval, saveval;
  118. char *filename;
  119. cfFILE *df;
  120. CFSTAT sbuf;
  121. void *xx, *xx1, *yy;
  122. int dlltype, dll_sn;
  123. char *cp;
  124.  
  125.     filename = strrchr(dllpath, '/');
  126.     if(filename)
  127.         ++filename;
  128.     else filename = dllpath;
  129.  
  130.     deflen = _strcpy(dlldef, filename);
  131.     if(strstr(dlldef, ".w32"))
  132.         dlltype = 1<<4;
  133.     else if(strstr(dlldef, ".os2"))
  134.         dlltype = 2<<4;
  135.     else if(strstr(dlldef, ".lnx"))
  136.         dlltype = 3<<4;
  137.     else if(strstr(dlldef, ".w16"))
  138.         dlltype = 4<<4;
  139.     else if(strstr(dlldef, ".os1"))
  140.         dlltype = 5<<4;
  141.     else
  142.         dlltype = 0;
  143.  
  144.     strcpy(curlib, "ltype3");
  145.     plib = cfsubopen(archive, curlib, F_RDWR|F_CREAT, NULL);
  146.     xx = cfsubopen(plib, dlldef, F_RDONLY, NULL);
  147.     if(!xx && delete)
  148.     {
  149.         cfprintf("cfar: %s does not exist\n", filename);
  150.         return;
  151.     }
  152.     if(xx && !(replace || delete))
  153.     {
  154.         cfclose(xx);
  155.         cfprintf("cfar: %s exists and replace not enabled\n", dlldef);
  156.         return;    
  157.     }
  158.     if(add || replace)
  159.     {
  160.         if(!(xx1 = cfopen(dllpath, F_RDONLY, NULL)))
  161.         {
  162.             cfclose(xx);
  163.             cfprintf("cfar: cannot open %s\n", dllpath);
  164.             return;
  165.         }
  166.         cfstat(xx1, &sbuf);
  167.         setup_origin(sbuf.st_mtime, 1);
  168.     }
  169.     symbol[0] = '_';    /* add leading underscore to symbols */
  170.     if(xx && (replace || delete))
  171.     {/* DELETE ALL OF THE OLD SYMBOLS */
  172.         saveval.sn = 0;
  173.  
  174.         /* get an in-memory uncompressed copy */
  175.         yy = cfsubopen(MEMTEMP, "", F_TEMPFILE, NULL);
  176.         filesize = cfunzip(yy,0,xx,0);
  177.         cfclose(xx);
  178.  
  179.         /* convert the memory file to a stream FILE */
  180.         cfseek(yy, 0, S_SET);
  181.         df = cffdopen(yy, "rt");
  182.         while(cffgets(buf, sizeof(buf)-1, df))
  183.         {
  184.           if( buf[0] == '#' || !isalnum(buf[0]) )
  185.             continue;
  186.           if(buf[0] == 'U' && strstr(buf, "UNHANDLED "))
  187.             break;
  188.           if(isdigit(buf[0]))
  189.           {
  190.             if(!strstr(buf, "ERROR:"))
  191.             {
  192.               /* the symbol is stored as oooo sssssssss cccc\n */
  193.               cfsscanf(buf, "%d %s %d", &ordinal, &symbol[1], &argcnt);
  194.  
  195.               /* Delete the symbol from msyms */
  196.               symlen = strlen(symbol);
  197.               dupnum = 0;
  198.               for(;;)
  199.               {
  200.               int    result = cffind_dupnum(msyms, symbol, symlen, &symval, &dupnum);
  201.  
  202.                 if(result >= FOUND)
  203.                 {
  204.                   symval.unused = 0;
  205.                   match = 0;
  206.                   if(saveval.sn)
  207.                   {
  208.                     if(symval.sn == saveval.sn && symval.libtype == 3)
  209.                     {
  210.                         match = 1;
  211.                     }
  212.                   }
  213.                   else
  214.                   {/* first */
  215.                     if(symval.libtype == 3)
  216.                     {/* check if the dll names match */
  217.                     int snum = symval.libnum;
  218.                        symval.libnum = 0;
  219.  
  220.                       if(cfget(qipaths, &symval, 8, buf, 256) >= FOUND)
  221.                       {
  222.                         if(!strcmp(buf, dllname))
  223.                         {
  224.                             symval.libnum = snum;
  225.                             saveval = symval;
  226.                             match = 1;
  227.                          }
  228.                        }
  229.                       }/* END: symval.libtype == 3 */
  230.                   }/* END: first */
  231.                   if(match)
  232.                   {
  233.                     if(cfdelete_dupnum(msyms, symbol, symlen, dupnum) != OK)
  234.                       cfprintf("cfar: ERROR can't delete %s dumpnum=%d\n",
  235.                             symbol, dupnum);
  236.                     break;
  237.                   }
  238.                   ++dupnum;
  239.                 }/* END: result >= FOUND */
  240.                 else break;
  241.               }/* END: for(;;) */
  242.             }/* END: !strstr(ERROR) */
  243.           }/* END: isdigit(buf[0]) */
  244.           else if((cp = strstr(buf, ".dll")))
  245.           {/* new dll encountered */
  246.             cp[4]=0;
  247.             if(saveval.sn)
  248.             {/* delete previous dll name from qipath */
  249.             int u = saveval.unused;
  250.             int n = saveval.libnum;
  251.                 saveval.unused = 0;
  252.                 saveval.libnum = 0;
  253.                 cfdelete(qipaths, &saveval, 8);
  254.                 saveval.unused = u;
  255.                 saveval.libnum = n;
  256.             }
  257.             strcpy(dllname, buf);
  258.             saveval.sn = 0;
  259.             if(verbose)
  260.                 cfprintf("delete %s\n", dllname);
  261.             continue;
  262.           }/* END: new dll encountered */            
  263.         }/* END: while(cffgets()) */
  264.  
  265.         /* delete last dllname from qipaths */
  266.         if(saveval.sn)
  267.         {
  268.             saveval.unused = 0;
  269.             saveval.libnum = 0;
  270.             cfdelete(qipaths, &saveval, 8);
  271.         }
  272.         cffclose(df); /* auto delete of tempfile yy */
  273.  
  274.         /* Delete the internal copy of dlldef */
  275.         cfdelete(plib, dlldef, deflen);
  276.         /* Delete the origin linkage */
  277.         strcat(dlldef, ".org");
  278.         cfdelete(plib, dlldef, deflen+4);
  279.         dlldef[deflen] = 0;
  280.     }/* END: DELETE OLD SYMBOLS */
  281.  
  282.     if(add || replace)
  283.     {/* INSERT NEW SYMBOLS */
  284.  
  285.         /* get the compressed file size */
  286.         filesize = cfzip(0,0,xx1,0);
  287.  
  288.         /* create a chunk to hold the compressed file */
  289.         xx = cfmake_chunk(plib, dlldef, deflen, filesize);
  290.         if(!xx)
  291.         {
  292.             cfprintf("cfar: cannot create internal file %s\n", filename);
  293.             cfclose(xx1);
  294.             return;
  295.         }
  296. #if 1
  297.         /* compress the external file into the internal chunk */
  298.         cfseek(xx1, 0, S_SET);
  299.         if((filesize1 = cfzip(xx,0,xx1,0)) != fil